/**
 * 
 */
package org.statewalker.fsm.config;

import org.statewalker.fsm.providers.FsmTransitionsConfigurator;
import org.statewalker.fsm.providers.FsmTransitionsRegistry;
import org.xml.sax.Attributes;

/**
 * @author kotelnikov
 */
public class FsmConfigParser extends ConfigParser {

    public static final String ATTR_EVENT = "event";

    public static final String ATTR_FROM = "from";

    public static final String ATTR_PROP_NAME = "name";

    public static final String ATTR_PROP_VALUE = "value";

    public static final String ATTR_STATE_KEY = "key";

    public static final String ATTR_TO = "to";

    protected FsmTransitionsConfigurator fConfig;

    protected FsmTransitionsRegistry fRegistry;

    /**
     * @param registry
     */
    public FsmConfigParser(FsmTransitionsRegistry registry) {
        fRegistry = registry;
        fConfig = new FsmTransitionsConfigurator(fRegistry);
        registerHandler("fsm/state", new NodeHandler() {
            @Override
            public void beginNode(
                String uri,
                String localName,
                String name,
                Attributes attributes) throws Exception {
                beginState(attributes);
            }

            @Override
            public void endNode(
                String uri,
                String localName,
                String name,
                Attributes attributes) throws Exception {
                endState(attributes);
            }
        });
        registerHandler("fsm/state/param", new NodeHandler() {
            @Override
            public void beginNode(
                String uri,
                String localName,
                String name,
                Attributes attributes) throws Exception {
                onProperty(attributes);
            }
        });
        registerHandler("fsm/state/transition", new NodeHandler() {
            @Override
            public void beginNode(
                String uri,
                String localName,
                String name,
                Attributes attributes) throws Exception {
                onTranistion(attributes);
            }
        });
        registerHandler("fsm/state/defaultTransition", new NodeHandler() {
            @Override
            public void beginNode(
                String uri,
                String localName,
                String name,
                Attributes attributes) throws Exception {
                onDefaultTransition(attributes);
            }
        });
    }

    protected void beginState(Attributes attributes) {
        String stateName = attributes.getValue(ATTR_STATE_KEY);
        String stateKey = getStateKey(stateName);
        fConfig.beginState(stateKey);
        int len = attributes.getLength();
        for (int i = 0; i < len; i++) {
            String name = attributes.getQName(i);
            if (!ATTR_EVENT.equals(name)
                && !ATTR_FROM.equals(name)
                && !ATTR_STATE_KEY.equals(name)
                && !ATTR_TO.equals(name)) {
                String value = attributes.getValue(i);
                fConfig.onStateProperty(name, value);
            }
        }
    }

    protected void endState(Attributes attributes) {
        fConfig.endState();
    }

    protected String getEventKey(String eventName) {
        return eventName;
    }

    protected String getStateKey(String stateName) {
        return stateName;
    }

    protected void onDefaultTransition(Attributes attributes) {
        String toName = attributes.getValue(ATTR_TO);
        String eventName = attributes.getValue(ATTR_EVENT);
        String event = getEventKey(eventName);
        String to = getStateKey(toName);
        fConfig.onDefaultTransition(event, to);
    }

    protected void onProperty(Attributes attributes) {
        String name = attributes.getValue(ATTR_PROP_NAME);
        String value = attributes.getValue(ATTR_PROP_VALUE);
        fConfig.onStateProperty(name, value);
    }

    protected void onTranistion(Attributes attributes) {
        String fromName = attributes.getValue(ATTR_FROM);
        String toName = attributes.getValue(ATTR_TO);
        String eventName = attributes.getValue(ATTR_EVENT);
        String from = getStateKey(fromName);
        String to = getStateKey(toName);
        String event = getEventKey(eventName);
        fConfig.onTransition(from, event, to);
    }

}
